package com.fingard.avatar.website.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fingard.avatar.website.exception.BizException;
import com.fingard.avatar.website.model.bean.LoginResp;
import com.fingard.avatar.website.model.enums.DeletedEnum;
import com.fingard.avatar.website.model.enums.RoleEnum;
import com.fingard.avatar.website.model.po.SysUserPo;
import com.fingard.avatar.website.service.SysUserService;
import com.fingard.avatar.website.service.SysUserTokenService;
import com.fingard.avatar.website.service.UserAuthService;
import com.fingard.avatar.website.utils.DaoUtils;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
import org.casbin.jcasbin.main.Enforcer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @author 徐一涛
 * @date 2022/4/26
 */
@Slf4j
@Service
public class UserAuthServiceImpl implements UserAuthService {

    @Resource
    protected SysUserService userService;
    @Resource
    protected SysUserTokenService tokenService;
    @Autowired
    protected Enforcer enforcer;

    private static final Cache<String, SysUserPo> CACHE = Caffeine.newBuilder()
            .expireAfterAccess(12, TimeUnit.HOURS)
            .initialCapacity(3)
            .build();


    @Override
    public SysUserPo getUser(String token) {
        return CACHE.get(token, x -> {
            Long userId = tokenService.getValidToken(token);
            if (ObjectUtil.isNotNull(userId)) {
                return userService.getById(userId);
            } else {
                return null;
            }
        });
    }

    @Override
    public void setUser(String token, SysUserPo user) {
        CACHE.put(token, user);
        tokenService.add(token, user.getId());
    }

    @Override
    public LoginResp login(String userName, String password) {
        String mdPwd = SecureUtil.md5(password);
        SysUserPo user = userService.getOne(Wrappers.<SysUserPo>lambdaQuery().
                eq(SysUserPo::getUserName, userName).
                eq(SysUserPo::getPassword, mdPwd).
                eq(SysUserPo::getIsDeleted, DeletedEnum.NOT_DELETED.getValue()));
        if (ObjectUtil.isNull(user)) {
            throw BizException.of("登录名或者密码错误");
        }

        String token = IdUtil.randomUUID();
        setUser(token, user);

        return new LoginResp().setUser(user).setToken(token);
    }

    @Override
    public boolean checkPermission(Object... params) {
        return enforcer.enforce(params);
    }

    @Override
    public SysUserPo getUserBySso(String userName) {
        SysUserPo user = userService.getOne(Wrappers.<SysUserPo>lambdaQuery().
                eq(SysUserPo::getUserName, userName).
                eq(SysUserPo::getIsDeleted, DeletedEnum.NOT_DELETED.getValue()));
        if (ObjectUtil.isNull(user)) {
            user = new SysUserPo();
            user.setUserName(userName).setPassword(SecureUtil.md5("1234567")).setRole(RoleEnum.USER.name());

            DaoUtils.insert(user, 0L);
            userService.save(user);
        }
        return user;
    }
}
